//
// Created by hunan on 25-7-13.
//

#include "download_fragment.h"

DownloadFragment::DownloadFragment(uint64_t data_size, int fragment_size)
{
    m_data_size     = data_size;
    m_fragment_size = fragment_size;
}

void DownloadFragment::FragmentDataSize()
{
    if (m_data_size <= m_fragment_size && m_data_size > 0)
    {
        m_fragments = {{0, Fragment{.m_min = 0, .m_max = m_fragment_size - 1, .m_status = EmInit}}};
    }
    else if (m_data_size > 0)
    {
        int min = 0, max = m_fragment_size;
        for (int index = 0; index < m_data_size; index += m_fragment_size)
        {
            Fragment data = {};
            data.m_status = EmInit;
            data.m_min = min;
            data.m_max = max - 1;
            data.m_max = (data.m_max > m_data_size) ? m_data_size - 1 : data.m_max;
            min += m_fragment_size;
            max += m_fragment_size;
            m_fragments[data.m_min] = data;
        }
    }
}

int DownloadFragment::RemoveLocalFragment(uint64_t data_size)
{
    int begin_index = 0;
    for (auto & data : m_fragments)
    {
        if ((data.second.m_max + 1) <= data_size)
        {
            data.second.m_status = EmDone;
        }
        else
        {
            begin_index = data.second.m_min;
            break;
        }
    }
    return begin_index;
}

bool DownloadFragment::IsFragmentDataSize() const
{
    return m_fragments.size() > 1 ? true : false;
}

bool DownloadFragment::GetOneFragment(int & min, int & max)
{
    for (auto & data : m_fragments)
    {
        if (data.second.m_status == EmDone || data.second.m_status == EmUsed)
        {
            continue;
        }
        min = data.second.m_min;
        max = data.second.m_max;
        data.second.m_status = EmUsed;
        return true;
    }
    return false;
}

void DownloadFragment::Update(int min, int max, int status)
{
    auto iter = m_fragments.find(min);
    if (iter != m_fragments.end() && iter->second.m_status != EmDone)
    {
        iter->second.m_status = status;
    }
}

int DownloadFragment::IsGetFragmentAll() const
{
    bool result = true;
    for (auto & data : m_fragments)
    {
        if (data.second.m_status != EmDone)
        {
            result = false;
            break;
        }
    }
    return result;
}



